package com.alvin.springshiro.controller;

import com.alvin.springshiro.model.Permission;
import com.alvin.springshiro.model.Role;
import com.alvin.springshiro.model.User;
import com.alvin.springshiro.service.UserRolePermissionService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.springframework.lang.Nullable;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@RestController
public class GenericController {

    private final UserRolePermissionService userRolePermissionService;

//    private final RedisTemplate<String,Object> redisTemplate;

    public GenericController(UserRolePermissionService userRolePermissionService/*, RedisTemplate<String, Object> redisTemplate*/) {
        this.userRolePermissionService = userRolePermissionService;
//        this.redisTemplate = redisTemplate;
    }

    @RequestMapping("/errorPage")
    public String errorPage(){

        log.error("进入了错误页");
        return "错误页";
    }

    @RequestMapping("/login")
    public Object doLogin(@RequestParam String username, @RequestParam String password) {

        if(StringUtils.isEmpty(username) || StringUtils.isEmpty(password)){
            return new ModelAndView("redirect:errorPage");
        }

        UsernamePasswordToken token = new UsernamePasswordToken(username, password);

        token.setRememberMe(true);

        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(token);

            log.info("shiro session 超时时间： " + subject.getSession().getTimeout());


        } catch (IncorrectCredentialsException ice) {
            return "password error!";
        } catch (UnknownAccountException uae) {
            return "username error!";
        } catch (Exception e){
            return e;
        }
        User user = userRolePermissionService.getUserByUserName(username);
        subject.getSession().setAttribute("user", user);

        Map<String,Object> mapUser = new HashMap<>();
        mapUser.put("user",user);

        return new ModelAndView("index", mapUser);
    }

    @RequiresRoles("general")
    @RequestMapping(value = "/user/{userId}")
    public User getUser(@PathVariable(name = "userId") int userId){
        return userRolePermissionService.getUserById(userId);
    }

    //即便设置了remember me，@RequiresAuthentication 注解的页面也需要重新登录才能访问
    //（设置了remember me）只有设置了设置RequiresAuthentication的页面，session超时才无法访问
    @RequiresRoles("admin")
    @RequiresAuthentication
    @RequestMapping(value = "/role/{userId}")
    public List<Role> getUserRoles(@PathVariable(name = "userId") int userId){
        log.info("展示user role");
        return userRolePermissionService.getUserRols(userId);
    }

    @RequestMapping(value = "/permission/{userId}")
    public List<Permission> getUserPermissions(@PathVariable(name = "userId") @Nullable int userId){
        return userRolePermissionService.getUserPermissions(userId);
    }


    @GetMapping(value = "/parameter/{param}")
    public ModelAndView showTheParameter(@PathVariable("param") String param){

        Map<String, String> model = new HashMap<>();
        model.put("parameter",param);
        model.put("telephone","123459");

        return new ModelAndView("param",model);
    }


    @RequestMapping("/logout")
    public Object doLogout() {

        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        Map<String, String> model = new HashMap<>();
        model.put("info","登出成功");
        return new ModelAndView("index",model);
    }

    @RequestMapping("/vuePage")
    public Object vuePage(){
        return new ModelAndView("vuePage");
    }


    @RequestMapping("/hello")
    public String hello(){
        return "this is hello world from Feign.";
    }

//    @RequestMapping("/setcache/{key}/{value}")
//    public String setCache(@PathVariable("key") String key, @PathVariable("value") String value){
//        long result = redisTemplate.opsForSet().add(key,value);
//        return "缓存设置成功：{key: " + key +", value: " + value + "}";
//    }
//
//    @RequestMapping("/getcache/{key}")
//    public String getCache(@PathVariable("key") String key){
//        Set<Object> result = redisTemplate.opsForSet().members("name");
//
//        StringBuffer stringBuffer = new StringBuffer();
//        result.stream().forEach(r -> {
//            stringBuffer.append(r + ",");
//        });
//
//        return "缓存获取成功：{key: " + key +", value: " + stringBuffer.toString() + "}";
//    }
//
//
//    @RequestMapping(value = "/setuser/{userId}")
//    public String setUserToRedis(@PathVariable(name = "userId") int userId){
//        User user = userRolePermissionService.getUserById(userId);
//
//        redisTemplate.opsForValue().set("user",user);
//        return "将用户放入缓存成功！";
//    }

    @Transactional
    @RequestMapping(value = "/adduserandrole")
    public String addUserWithTransaction(){
        User user1 = new User();
        user1.setName("name1");
        userRolePermissionService.addUser(user1);

        int temp = 1/0;

        Role role1 = new Role();
        role1.setName("role1");
        userRolePermissionService.addRole(role1);


        return "带事务的增加用户/角色成功";
    }

    @Transactional
    @RequestMapping(value = "/adduser/validation", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    public String addUserByValidation(@Valid @RequestBody User user){

        int id = userRolePermissionService.addUser(user);

        return "增加用户成功,id: " + user.getId();
    }
}
